<?php
/**
 * Desc: Service模板
 * User: zdb
 * Date: 2023/6/5
 * Time: 11:22
 */

namespace app\api\service\user;
use app\api\service\clockin\ClockinActivityService;
use app\api\service\LibraryService;
use app\api\service\setting\ClockinReviewRulePhaseService;
use app\util\DateUtil;
use think\facade\Db;

class UserClockinReviewService
{

    private $primaryTable;

    const ARR_REVIEW_EFFECT = array('in_heart' => 1, 'strange' => 2, 'not_familiar' => 3);

    public function __construct()
    {
        $this->primaryTable = "yj_user_clockin_review";
    }

    public function findRowById($id)
    {
        return Db::table($this->primaryTable)->alias('a')
            ->where('id', '=', $id)
            ->strict(false)
            ->find();
    }

    public function findRowByData($data)
    {
        $condition = $this->assembleFilterCondition($data);
        return Db::table($this->primaryTable)->alias('a')
            ->where($condition)
            ->strict(false)
            ->find();
    }

    public function getListByManyId($arrId)
    {
        $list = Db::table($this->primaryTable)->alias('a')
            ->whereIn('id', $arrId)
            ->select()
            ->toArray();
        return $list;
    }

    public function assembleFilterCondition($data)
    {
        if(isset($data['status'])){
            if(is_array($data['status'])){
                $condition = ['a.status '.$data[0].$data[1]];
            }else{
                $condition = ['a.status = '.$data['status']];
            }
        }else{
            $condition = array();
        }

        if (!empty($data['title'])) {
            $condition[] = "title like '%" . $data['title'] . "%'";
        }

        if (!empty($data['example_id'])) {
            $condition[] = "example_id =".$data['example_id'];
        }

        if (!empty($data['arr_id'])) {
            $condition[] = "a.id in (".implode(",", $data['arr_id']).")";
        }

        return empty($condition) ? "" : implode(" AND ", $condition);
    }

    public function getListNoPage($data = [], $limitNum = 30)
    {
        $condition = $this->assembleFilterCondition($data);
        $res = Db::table($this->primaryTable)->alias('a')
            ->where($condition)
            ->limit(0, $limitNum)
            ->order('a.id desc')
            ->select()
            ->toArray();
        return $res;
    }

    public function getListWithPage($data, $pageIndex = 1, $pageSize = 30)
    {
        $offset = ($pageIndex - 1) * $pageSize;
        $condition = $this->assembleFilterCondition($data);

        if($data['resource_type'] == ClockinActivityService::ARR_CONTENT_TYPE['poem']){
            $list = Db::table($this->primaryTable)->alias('a')
                ->leftJoin("yj_clockin_activity_plan_task pt", "pt.id = a.plan_task_id")
                ->leftJoin("yj_clockin_activity ca", "ca.id = pt.clockin_activity_id")
                ->leftJoin("yj_lib_poem p", "p.id = pt.subject_id")
                ->leftJoin("yj_user u", "u.id = a.user_id")
                ->where($condition)
                ->field("a.*, pt.plan_date, pt.subject_id, ca.activity_name, p.poem_title, p.poet, p.dynasty, u.account,u.nickname, u.real_name")
                ->limit($offset, $pageSize)
                ->order('a.id desc')
                ->select()
                ->toArray();
        }else if($data['resource_type'] == ClockinActivityService::ARR_CONTENT_TYPE['movie_word_en']){
            $list = Db::table($this->primaryTable)->alias('a')
                ->leftJoin("yj_clockin_activity_plan_task pt", "pt.id = a.plan_task_id")
                ->leftJoin("yj_clockin_activity ca", "ca.id = pt.clockin_activity_id")
                ->leftJoin("yj_lib_movie_word mw", "mw.id = pt.subject_id")
                ->leftJoin("yj_lib_movie m", "m.id = mw.movie_id")
                ->leftJoin("yj_user u", "u.id = a.user_id")
                ->where($condition)
                ->field("a.*, pt.plan_date, pt.subject_id, ca.activity_name, m.movie_name_cn, mw.spelling, u.account,u.nickname, u.real_name")
                ->limit($offset, $pageSize)
                ->order('a.id desc')
                ->select()
                ->toArray();
        }

        return $list;
    }

    public function getTotalNum($data)
    {
        $condition = $this->assembleFilterCondition($data);
        $num = Db::table($this->primaryTable)->alias('a')
            ->where($condition)
            ->count();
        return $num;
    }

    public function createRow($data)
    {
        $data['status'] = isset($data['status']) ? $data['status']:1;
        $res = Db::table($this->primaryTable)
            ->strict(false)
            ->insert($data, true);
        return $res;
    }

    public function createManyRow($data)
    {
        $res = Db::table($this->primaryTable)
            ->strict(false)
            ->insertAll($data, true);
        return $res;
    }

    public function updateRowById($id, $data)
    {
        $res = Db::table($this->primaryTable)->alias('a')
            ->where('id', '=', $id)
            ->strict(false)
            ->save($data);
        return false !== $res ? true : false;
    }

    public function updateListByData($condition, $data)
    {
        $condition = $this->assembleFilterCondition($condition);
        $res = Db::table($this->primaryTable)->alias('a')
            ->where($condition)
            ->save($data);
        return false !== $res ? true : false;
    }

    public function updateListByManyId($arrId, $data)
    {
        $res = Db::table($this->primaryTable)->alias('a')
            ->whereIn('a.id', $arrId)
            ->strict(false)
            ->save($data);
        return false !== $res ? true : false;
    }

    public function removeRowById($id)
    {
        $data = ['status' => 0];
        $res = Db::table($this->primaryTable)
            ->where('id', '=', $id)
            ->strict(false)
            ->save($data);
        return false !== $res ? true : false;
    }

    public function removeListByManyId($arrId)
    {
        $data = ['status' => 0];
        $res = Db::table($this->primaryTable)->alias('a')
            ->whereIn('a.id', $arrId)
            ->strict(false)
            ->save($data);
        return false !== $res ? true : false;
    }

    public function removeListByData($data)
    {
        $condition = $this->assembleFilterCondition($data);
        $data = ['status' => 0];
        $res = Db::table($this->primaryTable)->alias('a')
            ->where($condition)
            ->save($data);
        return false !== $res ? true : false;
    }

    /**
     * 后台帮助温习
     * 如果记住，进入下一阶段
     * 如果不熟悉，从头再来
     * 如果待巩固，重复当前阶段
     * @param $arrId
     * @param $isInMind
     */
    public function helpReview($arrId, $isInMind)
    {
        $list = $this->getListNoPage(array('arr_id' => $arrId));
        $serviceClockinReviewRulePhase = new ClockinReviewRulePhaseService();
        $nowTime = DateUtil::getCurrentDatetime();

        Db::table($this->primaryTable)->startTrans();
        try {
            foreach ($list as $item) {
                if ($item['deadline'] < $nowTime) {
                    //已延误
                    $isDelay = 1;
                } else {
                    $isDelay = 2;
                }
                $updateData = array(
                    'is_review' => 1,
                    'review_time' => $nowTime,
                    'is_in_mind' => $isInMind,
                    'is_delay' => $isDelay
                );
                $res = $this->updateRowById($item['id'], $updateData);
                if (!$res) {
                    throw new \Exception("更新温习进度失败");
                }

                $rulePhaseId = $item['rule_phase_id'];
                $rulePhaseInfo = $serviceClockinReviewRulePhase->findRowById($rulePhaseId);

                if ($isInMind == self::ARR_REVIEW_EFFECT['in_heart']) {
                    $newRulePhaseInfo = $serviceClockinReviewRulePhase->getNextRulePhase($rulePhaseInfo);
                    if(empty($newRulePhaseInfo)){
                        //温习阶段全部结束
                        $insertRulePhaseId = 0;
                    }else{
                        $insertRulePhaseId = $newRulePhaseInfo['id'];
                    }
                } else if ($isInMind == self::ARR_REVIEW_EFFECT['strange']) {
                    $newRulePhaseInfo = $serviceClockinReviewRulePhase->getFirstRulePhase($rulePhaseInfo);
                    $insertRulePhaseId = $newRulePhaseInfo['id'];
                } else {
                    //待巩固，重复当前阶段
                    $insertRulePhaseId = $item['rule_phase_id'];
                    $newRulePhaseInfo = $rulePhaseInfo;
                }

                if($insertRulePhaseId){
                    $showTime = $serviceClockinReviewRulePhase->getReviewShowTime($newRulePhaseInfo, $nowTime);
                    $deadlinePhaseInfo = $serviceClockinReviewRulePhase->getNextRulePhase($newRulePhaseInfo);
                    $deadline = $serviceClockinReviewRulePhase->getReviewShowTime($deadlinePhaseInfo, $showTime);
                    $insertData = array(
                        'user_id' => $item['user_id'],
                        'plan_task_id' => $item['plan_task_id'],
                        'rule_phase_id' => $insertRulePhaseId,
                        'show_time' => $showTime,
                        'deadline'  => $deadline,
                        'is_review' => 2,
                    );
                    $resAdd = $this->createRow($insertData);
                    if(!$resAdd){
                        throw new \Exception("下一阶段温习数据创建失败");
                    }
                }
            }
            Db::table($this->primaryTable)->commit();
            return array('flag' => 1, 'message' => "");
        }catch(\Exception $e){
            Db::table($this->primaryTable)->rollback();
            return array('flag' => 0, 'message' => $e->getMessage());
        }
    }

}